package com.xp.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xp.entity.RoleMenu;
import com.xp.mapper.RoleMenuMapper;
import com.xp.service.RoleMenuService;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 角色菜单关联服务实现类
 * 
 * @author xp
 * @since 2024-01-01
 */
@Service
@RequiredArgsConstructor
public class RoleMenuServiceImpl extends ServiceImpl<RoleMenuMapper, RoleMenu> implements RoleMenuService {

    private static final Logger log = LoggerFactory.getLogger(RoleMenuServiceImpl.class);

    private final RoleMenuMapper roleMenuMapper;

    /**
     * 根据角色ID查询菜单ID列表
     */
    @Override
    public List<Long> getMenuIdsByRoleId(Long roleId) {
        return roleMenuMapper.selectMenuIdsByRoleId(roleId);
    }

    /**
     * 根据菜单ID查询角色ID列表
     */
    @Override
    public List<Long> getRoleIdsByMenuId(Long menuId) {
        return roleMenuMapper.selectRoleIdsByMenuId(menuId);
    }

    /**
     * 为角色分配菜单
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean assignMenusToRole(Long roleId, List<Long> menuIds) {
        try {
            // 先删除该角色的所有菜单关联
            removeMenusByRoleId(roleId);
            
            // 如果菜单ID列表为空，则只删除不添加
            if (menuIds == null || menuIds.isEmpty()) {
                return true;
            }
            
            // 批量插入新的角色菜单关联
            List<RoleMenu> roleMenus = menuIds.stream()
                    .map(menuId -> {
                        RoleMenu roleMenu = new RoleMenu();
                        roleMenu.setRoleId(roleId);
                        roleMenu.setMenuId(menuId);
                        roleMenu.setCreateTime(LocalDateTime.now());
                        roleMenu.setUpdateTime(LocalDateTime.now());
                        return roleMenu;
                    })
                    .collect(Collectors.toList());
            
            return saveBatch(roleMenus);
        } catch (Exception e) {
            log.error("为角色分配菜单失败，角色ID: {}, 菜单IDs: {}", roleId, menuIds, e);
            return false;
        }
    }

    /**
     * 删除角色的所有菜单关联
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeMenusByRoleId(Long roleId) {
        try {
            LambdaQueryWrapper<RoleMenu> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(RoleMenu::getRoleId, roleId);
            return remove(queryWrapper);
        } catch (Exception e) {
            log.error("删除角色菜单关联失败，角色ID: {}", roleId, e);
            return false;
        }
    }

    /**
     * 删除菜单的所有角色关联
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeRolesByMenuId(Long menuId) {
        try {
            LambdaQueryWrapper<RoleMenu> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(RoleMenu::getMenuId, menuId);
            return remove(queryWrapper);
        } catch (Exception e) {
            log.error("删除菜单角色关联失败，菜单ID: {}", menuId, e);
            return false;
        }
    }
}